package us.wili.dev.netty.service.impl;

import com.alibaba.fastjson.JSON;
import com.qiniu.util.Json;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import us.wili.dev.common.util.dateTime.DateUtil;
import us.wili.dev.model.entity.User;
import us.wili.dev.netty.model.GameLog;
import us.wili.dev.netty.model.GameResponseDto;
import us.wili.dev.netty.model.PlayerOpt;
import us.wili.dev.netty.model.RequestCmd;
import us.wili.dev.netty.model.game.*;
import us.wili.dev.netty.service.*;
import us.wili.dev.netty.util.CardGroup;
import us.wili.dev.netty.util.CardUtil;

import javax.jws.soap.SOAPBinding;
import java.security.interfaces.RSAKey;
import java.util.*;

@Service
public class NettyRoomServiceImpl implements NettyRoomService {

    @Autowired
    private UserService userService;
    @Autowired
    private NettyEventService eventService;
    @Autowired
    private NettyMsgEventService msgEventService;
    @Autowired
    private NettyBetPoolService poolService;

    @Override
    public Room startGame(Room room) {
        if (room.getGamestate().compareAndSet(0, 1)) {
            //游戏日志-玩家操作信息
            room.setOpts(new ArrayList<>());

            //需要通知在结束阶段进入的玩家牌局信息
            //所以延迟到下局才清理上局信息
            room.getFinalCardsMap().clear();
            room.getHandCardsMap().clear();
            room.getWinPlayersMap().clear();

            //重新补筹码
            for (Player p : room.getWaitPlayers()) {
                if (p.getBodyChips() == 0) {
                    assignChipsForInRoom(p, room.getMaxChips());
                }
            }
            //总筹码不足的不能进行游戏，自动踢出房间
            room.getWaitPlayers().parallelStream().filter(p -> p.getBodyChips() <= 0).forEach(p -> outRoom(p, room));
            //转移等待列表的玩家 加入游戏中玩家列表
            movePlayers(room.getWaitPlayers(), room.getIngamePlayers());
            //记录玩家座位号
            for (Player p : room.getIngamePlayers()) {
                p.setFold(false);
            }
            //更新下一个dealer
            updateNextDealer(room);
            //得到洗好的牌 （随机卡组）
            room.setCardList(CardGroup.getRandomCards());
            //确定大小盲主，并分配筹码到奖池
            //最佳位置
            Integer dealer = room.getDealer();
            //小盲注
            Integer smallBet = room.getSmallBet();
            //大盲注
            Integer bigBet = room.getBigBet();
            //小盲位置
            Integer smallBetSeat = getNextSeatNum(dealer,room);
            //当只有两个玩家时，dealer才是小盲
            if (room.getIngamePlayers().size()==2){
                smallBetSeat = dealer;
            }
            room.setSmallBetSeatNum(smallBetSeat);
            //大盲位置
            Integer bigBetSeat = getNextSeatNum(smallBetSeat,room);
            room.setBigBetSeatNum(bigBetSeat);
            //小盲玩家
            Player smallBetPlayer = getPlayerBySeatNum(smallBetSeat,room.getIngamePlayers());
            //大盲玩家
            Player bigBetPlayer = getPlayerBySeatNum(bigBetSeat,room.getIngamePlayers());
            //大小盲玩家下注
            betChipsIn(smallBetPlayer,smallBet,false,room);
            betChipsIn(bigBetPlayer,bigBet,false,room);
            //更新下一个该操作的玩家
            room.setNextturn(getNextNum(bigBetSeat,room));
            //更新下一轮该操作的玩家为小盲位置
            room.setRoundturn(smallBetSeat);
            //当只有两个玩家时，第一轮dealer（同时也是小盲） 先操作
            //第二轮开始大盲先操作
            if (room.getIngamePlayers().size()==2){
                room.setRoundturn(bigBetSeat);
            }
            //分发手牌
            assignHandPokerByRoom(room);
            //通知房间中在游戏中的玩家此刻的房间（包含私有信息【公共牌+手牌】的房间）
            for (Player p : room.getIngamePlayers()) {
                PrivateRoom privateRoom = new PrivateRoom();
                privateRoom.setRoom(room);
                //私有信息（手牌）
                privateRoom.setHandPokers(p.getHandPokers());
                GameResponseDto rsp  =new GameResponseDto();
                rsp.setRequestId("onGameStart");
                rsp.setCmd(RequestCmd.GAME_PLAYER_HANDPOKER.getCode());
                rsp.setData(privateRoom);
                msgEventService.sendMsgToPlayer(p,rsp);
            }
            startTimer(room);
            room.setGameLog(new GameLog());
            room.getGameLog().setStartTime(DateUtil.nowDatetime());
            String initInfo = JSON.toJSONString(room.getIngamePlayers());
            room.getGameLog().setPlayersInitInfo(initInfo);
            room.getGameLog().setRoomType("普通");
            room.getGameLog().setBigBet(JSON.toJSONString(bigBetPlayer));
            room.getGameLog().setSmallBet(JSON.toJSONString(smallBetPlayer));
            room.getGameLog().setDealer(JSON.toJSONString(getPlayerBySeatNum(dealer,room.getIngamePlayers())));
        }
        return room;
    }

    @Override
    public void assignChipsForInRoom(Player player, Integer maxChips) {
        long takeChip = maxChips;
        // 如果玩家的所剩筹码不超过房间规定的最大带入筹码，则该玩家筹码全部带入
        if (player.getChips() < takeChip) {
            takeChip = player.getChips();
        }
        synchronized (player) {
            player.setChips(player.getChips() - takeChip);
            player.setBodyChips(takeChip);
        }
    }

    @Override
    public void outRoom(Player player, Room room) {
        if (player == null || room == null) {
            return;
        }
        synchronized (room.getFreeSeatStack()) {
            Room tempRoom = room;
            sendPlayerToOther(player, tempRoom);
            removeWaitOrInGamePlayer(player, room);
            //成功设置房间
            int index = room.donePlayerList.indexOf(player.getSeatNum());
            if (index != -1) {
                room.donePlayerList.remove(index);
            }
            //记录玩家筹码的变化
            assignChipsForOutRoom(player);
            //还座位号
            if (player.getSeatNum() != -1) {
                room.getFreeSeatStack().push(player.getSeatNum());
            }
            //修改房间状态为可加入
            room.setRoomstate(1);


        }
    }

    @Override
    public void sendMsgToOne(Player p, GameResponseDto msg) {
        if (p != null) {

            eventService.sendText(p.getSession(), msg);
        }
    }

    @Override
    public void sendPlayerToOther(Player player, Room room) {
        String currPlayerInfo = JSON.toJSONString(player);
        sendMessageToOtherPlays(player.getId(), room, currPlayerInfo);
    }

    @Override
    public void sendMessageToOtherPlays(Long selfID, Room room, String msg) {
        if (room == null) {
            return;
        }
        GameResponseDto gameResponseDto = new GameResponseDto();
        gameResponseDto.setCmd(RequestCmd.GAME_LEFT.getCode());
        gameResponseDto.setData(msg);
        // 通知其他玩家
        List<Player> waitPlayers = room.getWaitPlayers();
        for (Player p : waitPlayers) {
            if (p != null && p.getId() != selfID) {
                UUID _session = p.getSession();
                eventService.sendText(_session, gameResponseDto);
            }

        }
        List<Player> ingamePlayers = room.getIngamePlayers();
        for (Player p : ingamePlayers) {
            if (p != null && p.getId() != selfID) {
                UUID _session = p.getSession();
                eventService.sendText(_session, gameResponseDto);
            }

        }
    }

    @Override
    public void removeWaitOrInGamePlayer(Player player, Room room) {
        removeWaitPlayer(player, room);
        removeIngamePlayer(player, room);
    }

    @Override
    public void assignChipsForOutRoom(Player player) {
        synchronized (player) {
            // 当前筹码数等于桌上筹码+身上筹码
            player.setChips(player.getChips() + player.getBodyChips());
            player.setBodyChips(0);
            // 玩家筹码信息入库
            userService.increaseBalance(player.getId(), player.getChips(), 1);
        }
    }

    @Override
    public Boolean checkEnd(Room room) {
        int playCount = 0;
        for (Player p : room.getIngamePlayers()) {
            if (!p.isFold() && p.getBodyChips() != 0) {
                playCount++;
            }
        }
        if (playCount < 2) {
            endGame(room);
            return true;
        }
        System.out.println(playCount + "断线后人数大于1");
        return false;
    }

    @Override
    public void endGame(Room room) {
        Date now = new Date();
        //尝试更新游戏状态为2：结算中
        if (room.getGamestate().compareAndSet(1, 2)) {
            //TODO:结算逻辑
            int allinCount = 0;
            //统计allin玩家数
            for (Player p : room.getIngamePlayers()) {
                if (p.getBodyChips() == 0) {
                    allinCount++;
                }
            }
            //如果公共牌没发完 切allin大于等于两个人则先发完公共牌
            if (room.getCommunityCards().size() < 5 && allinCount >= 2) {
                //发公共牌
                Integer assignCardCount = 5 - room.getCommunityCards().size();
                assignCommonCardByNum(room, assignCardCount);
            }
            int timeBetween = room.getRestBetweenGame();
            if (room.getCommunityCards().size() == 5) {
                //成手牌列表
                for (Player p : room.getIngamePlayers()) {
                    List<Integer> hankPoker = new ArrayList<>();
                    List<Integer> hankPokerAndCommonCard = new ArrayList<Integer>();
                    hankPokerAndCommonCard.addAll(room.getCommunityCards());
                    for (int i = 0; i < p.getHandPokers().length; i++) {
                        hankPokerAndCommonCard.add(p.getHandPokers()[i]);
                        hankPoker.add(p.getHandPokers()[i]);
                    }
                    // 判断牌型并将牌型编号加在数组最后一位
                    List<Integer> maxCardsGroup = CardUtil.getMaxCardsGroup(hankPokerAndCommonCard);
                    // 加入成手牌列表
                    room.getFinalCardsMap().put(p.getSeatNum(), maxCardsGroup);
                    // 加入互相可见的手牌列表
                    room.getHandCardsMap().put(p.getSeatNum(), hankPoker);
                }
            } else {
                //牌没发完，等待时间减少
                timeBetween = 3000;
            }
            //奖池列表
            List<BetPool> betPoolList = new ArrayList<BetPool>();
            //计算betpool
            poolService.subBetPoolList(betPoolList, room.getBetMap(), room.getIngamePlayers());
            //对每个分池结算
            for (BetPool betPool : betPoolList) {
                //单个分池中的获胜玩家列表
                List<Player> winPlayersList = betPool.getBetPlayerList();
                //本分池的玩家列表
                List<Player> poolPlayers = betPool.getBetPlayerList();
                if (room.getFinalCardsMap().size() > 0) {
                    //获取本分池获胜玩家
                    winPlayersList = poolService.compareCardsToWinList(poolPlayers, room.getFinalCardsMap());
                }
                //没有则认为第一个获胜，若公共牌未发完结束游戏，存在该情况
                if (winPlayersList.size() == 0) {
                    for (Player p : poolPlayers) {
                        winPlayersList.add(p);
                        break;
                    }
                }
                Long win = 0l;
                if (winPlayersList.size() != 0) {
                    //本次分池获胜的玩家分筹码
                    win = (Long) (betPool.getBetSum() / winPlayersList.size());
                }
                for (Player p : winPlayersList) {
                    poolService.increasePlayerChips(p, win);
                    //在上个分池中已经赢得筹码 需要合并计算 加入winplayersmap
                    Long lastPoolWin = room.getWinPlayersMap().get(p.getSeatNum());
                    if (lastPoolWin != null) {
                        win += lastPoolWin;
                    }
                    room.getWinPlayersMap().put(p.getSeatNum(), win);
                    //排行榜
                    //TODO:排行榜押后
                }
            }
        }

        //发送结算消息
        GameResponseDto rsp = new GameResponseDto();
        rsp.setRequestId("onGameEnd");
        rsp.setData(JSON.toJSONString(room));
        rsp.setCmd(RequestCmd.DECLARE_ROOM_GAME_ENDCOUT.getCode());
        msgEventService.sendMsgToPlayerByRoom(room, rsp);

        //清除本局状态信息
        room.getBetMap().clear();
        //清除betroundMap
        room.getBetRoundMap().clear();
        //清除每轮最大加注倍数
        room.setRoundMaxBet(1);
        //清除手牌
        for (Player p : room.getIngamePlayers()) {
            p.setHandPokers(null);
        }
        //清除已操作的玩家列表
        room.getDonePlayerList().clear();
        //清除总下注
        room.setBetAmount(0);
        //清除公共牌
        room.getCommunityCards().clear();
        ;
        //清除牌堆
        room.getCardList().clear();
        //将所有玩家移入等待列表
        movePlayers(room.getIngamePlayers(), room.getWaitPlayers());

        //更新玩家数据到数据库
        System.out.printf("updatePlayer ingamePlayers begin size:" + room.getIngamePlayers().size());
        for (Player p : room.getWaitPlayers()) {
            User user = new User();
            user.setId(p.getId());
            user.setChips(p.getChips() + p.getBodyChips());
            synchronized (p) {
                userService.update(user);
            }
        }

        //记录游戏日志 押后

        Date costEnd = new Date();
        long cost = costEnd.getTime() - now.getTime();
        if (cost > 500) {
            System.out.println("endGame:" + " cost Millisecond" + cost);
        }
        // 尝试更新游戏状态为0：等待开始
        room.getGamestate().compareAndSet(2, 0);
        // 判断是否可以开始下一局
        //checkStart(timeBetween);
    }

    @Override
    public Boolean inRoom(Room room, Player player) {
        if (room == null) {
            return false;
        }
        //房间加锁
        synchronized (room.getFreeSeatStack()) {
            //房间满人，修改状态不可加入
            if (room.getFreeSeatStack().isEmpty()) {
                room.setRoomstate(0);
                return false;
            }
            room.getWaitPlayers().add(player);
            //设定座位号
            if (player.getSeatNum() == -1) {
                int seatNum = room.getFreeSeatStack().pop();
                player.setSeatNum(seatNum);
            }
            assignChipsForInRoom(player, room.getMaxChips());

        }
        return true;
    }

    @Override
    public void assignCommonCardByNum(Room room, Integer num) {
        List<Integer> carList = room.getCardList();
        for (int i = 0; i < num; i++) {
            room.getCommunityCards().add(carList.get(0));
            carList.remove(0);
        }
        GameResponseDto rsp = new GameResponseDto();
        rsp.setCmd(RequestCmd.DECLARE_ROOM_COMMONCARD.getCode());
        rsp.setData(room.getCommunityCards());
        msgEventService.sendMsgToPlayerByRoom(room, rsp);

    }

    @Override
    public Player getPlayerBySeatNum(Integer seatNum, List<Player> playerList) {
        Optional<Player> player = null;
        player = playerList.parallelStream().filter(p -> p.getSeatNum() == seatNum).findFirst();
        if (player.isPresent()) {
            return player.get();
        } else {
            return null;
        }
    }

    @Override
    public void movePlayers(List<Player> from, List<Player> to) {
        while (from.size() > 0) {
            to.add(from.get(0));// 添加来源列表的首位到目标列表
            from.remove(0);// 移除来源列表的首位
        }
    }

    @Override
    public Boolean betChipsIn(Player player, Integer chip, Boolean playerOpt, Room room) {
        if (player == null) {
            return false;
        }
        if (playerOpt && player.getSeatNum() != room.getNextturn()) {
            return false;
        }

        PlayerOpt opt = new PlayerOpt();
        opt.setOptChips(chip);
        opt.setOptTime(DateUtil.nowDatetime());
        opt.setOptType("");// 操作类型（跟注、加注、弃牌、全下）
        //第几轮
        Integer rd = Math.abs(room.getCommunityCards().size());
        opt.setRound(rd);
        opt.setRemark("");//备注
        opt.setPlayerId(player.getId().toString());
        opt.setSeatNum(player.getSeatNum());
        room.getOpts().add(opt);

        //玩家此次下注前的本轮下注额
        long oldBetThisRound = 0;
        if (room.getBetRoundMap().get(player.getSeatNum()) != null) {
            oldBetThisRound = room.getBetRoundMap().get(player.getSeatNum());
        }
        if (playerOpt) {
            //无效下注额 1筹码不足
            if (chip <= 0 || chip > player.getBodyChips()) {
                System.out.printf("not enough chips:" + chip + " getBodyChips():" + player.getBodyChips());
                return false;
            }
            //2.在没有allin的情况下 如果不是跟住，则下注必须是大于大盲的整数倍
            if (chip < player.getBodyChips()) {
                //1.不能小于之前的下注
                if ((chip + oldBetThisRound) < room.getRoundMaxBet()) {
                    System.out.printf("< getRoundMaxBet() chip:" + chip + "oldBetThisRound:" + oldBetThisRound
                            + " max:" + room.getRoundMaxBet());
                    return false;
                }
                if ((chip + oldBetThisRound) != room.getRoundMaxBet()) {
                    if ((chip + oldBetThisRound) % room.getRoundMaxBet() != 0) {
                        System.out.printf("% getBigBet() != 0:" + chip + "oldBetThisRound:" + oldBetThisRound);
                        return false;
                    }
                }
            }
        }
        try {
            if (playerOpt) {
                cancelTime(room);
            }
            //设置本轮最大加注
            if (chip > room.getRoundMaxBet()) {
                room.setRoundMaxBet(chip);
                //加注额大于之前，则所有玩家重新加注
                room.getDonePlayerList().clear();
            }
            //总奖池
            room.setBetAmount(room.getBetAmount() + chip);
            //记录当前轮已经操作过的玩家
            if (!room.getDonePlayerList().contains(player.getSeatNum()) && playerOpt) {
                room.getDonePlayerList().add(player.getSeatNum());
            }
            //刷新下注列表
            Long beforeBet = 0l;
            if (room.getBetMap().get(player.getSeatNum()) != null) {
                beforeBet = room.getBetMap().get(player.getSeatNum());
            }
            //加入玩家总下注map
            room.getBetMap().put(player.getSeatNum(), beforeBet + chip);
            //加入玩家本轮下注map
            room.getBetMap().put(player.getSeatNum(), chip + oldBetThisRound);
            //筹码入池
            player.setBodyChips(player.getBodyChips() - chip);
        } catch (Exception ex) {

        }
        if (playerOpt) {
            try {
                BetPlayer bp = new BetPlayer();
                bp.setBodyChips(player.getBodyChips());
                bp.setInChips(chip);
                bp.setSeatNum(player.getSeatNum());
                GameResponseDto rsp = new GameResponseDto();
                rsp.setCmd(RequestCmd.DECLARE_ROOM_GAME_DOWNBET.getCode());
                rsp.setRequestId("onPlayerBet");
                rsp.setData(bp);
                msgEventService.sendMsgToPlayerByRoom(room, rsp);
            } catch (Exception ex) {

            }
        }
        return true;
    }

    @Override
    public void startTimer(Room room) {
        if (room.getTt() != null) {
            room.getTt().cancel();
            room.setTt(null);
        }
        room.getTimer().purge();
        room.setTt(new TimerTask() {
            @Override
            public void run() {
                try {
                    //弃牌 or check
                    Player p = getPlayerBySeatNum(room.getNextturn(), room.getIngamePlayers());
                    if (p != null) {
                        //帮其执行弃牌操作
                        System.out.printf(p.getNickName() + " time is up,fold");
                        fold(room, p);
                    } else {
                        if (room.getGamestate().get() == 1) {
                            //更新本应操作的玩家
                            updateNextTurn(room);
                            //发送到某玩家操作的消息
                            msgEventService.sendNextTurnMessage(room.getNextturn(), room);
                        }
                    }
                } catch (Exception ex) {
                    System.out.printf("timer出错 roomID是" + room.getId());
                }
            }
        });

        // 考虑到网络传输延时，后台计时器多给与一个500毫秒的缓冲时间
        room.getTimer().schedule(room.getTt(), room.getOptTimeout() + 500);
    }

    @Override
    public void cancelTime(Room room) {
        if (room.getTt() != null) {
            room.getTt().cancel();
            room.setTt(null);
        }

    }

    @Override
    public void fold(Room room, Player player) {
        //房间状态游戏中
        if (room.getGamestate().get() != 1) {
            return;
        }
        if (player.getSeatNum() != room.getNextturn()) {
            return;
        }
        try {
            cancelTime(room);
            synchronized (player) {
                player.setFold(true);
            }
            //发送棋牌消息给玩家
            GameResponseDto rsp = new GameResponseDto();
            rsp.setCmd(RequestCmd.DECLARE_ROOM_GAME_FOLD.getCode());
            rsp.setRequestId("onPlayerFold");
            rsp.setData(player);
            msgEventService.sendMsgToPlayerByRoom(room, rsp);
            //将玩家移动到等待列表
            removeIngamePlayer(player, room);
            Integer index = room.getDonePlayerList().indexOf(player.getSeatNum());
            //玩家在donePlayerList，则移除
            if (index != -1) {
                room.getDonePlayerList().remove(index);
            }
            room.getWaitPlayers().add(player);

        } catch (Exception ex) {

        }

        //判断下一步是否round结束，endgame或者下一个玩家操作

    }

    @Override
    public void endRoundOrNextTurn(Room room) {
        Boolean roundEnd = checkRoundEnd(room);
    }

    @Override
    public Boolean checkRoundEnd(Room room) {
        //判断本轮是否可以结束
        Boolean canEndRound = true;
        if (room.getIngamePlayers().size() == 1) {
            //结算游戏
            System.out.printf("only one IngamePlayers endgame start");
            endGame(room);
            return true;
        }
        //将已经allin的玩家加入已操作列表
        for (Player p : room.getIngamePlayers()) {
            if (p.getBodyChips() == 0) {
                room.getDonePlayerList().add(p.getSeatNum());
            }
        }
        //所有人已经操作过
        if (room.getDonePlayerList().size() >= room.getIngamePlayers().size()) {
            Long betMax = 0l;//以最大下注作为参照筹码
            for (Player p : room.getIngamePlayers()) {
                //为betmax复制
                if (room.getBetMap().get(p.getSeatNum()) != null && room.getBetMap().get(p.getSeatNum()) > betMax) {
                    betMax = room.getBetMap().get(p.getSeatNum());
                }
            }
            System.out.printf("checkRoundEnd betMax:" + betMax);
            for (Player p : room.getIngamePlayers()) {
                //已经弃牌的排除在外
                if (p == null || p.isFold()) {
                    continue;
                }
                if (room.getBetMap().get(p.getSeatNum()) == null) {
                    //存在没有下注的玩家
                    System.out.printf("checkRoundEnd no bet seatNum:" + p.getSeatNum());
                    canEndRound = false;
                    break;
                }
                //没有allin的玩家中
                if (p.getBodyChips() > 0) {
                    //没有弃牌的玩家中 存在下注额度小于betmax，则本轮不能结束
                    if (betMax > room.getBetMap().get(p.getSeatNum())) {
                        System.out.printf("not allin bet<maxbet seatNum:" + p.getSeatNum() + " bet "
                                + room.getBetMap().get(p.getSeatNum()) + " betMax:" + betMax);
                        canEndRound = false;
                        break;
                    }
                }
            }
        } else {
            System.out.printf("checkRoundEnd getDonePlayerList().size() < getIngamePlayers().size()");
            canEndRound = false;
        }

        //如果下一个可以操作的玩家无法更新，游戏结束
        Integer turn = getNextSeatNum(room.getNextturn(), room);
        if (turn == room.getNextturn()) {
            canEndRound = true;
        }
        if (canEndRound) {
            System.out.printf("CanEndRound =ture");
            //第二轮最低加注设为0
            room.setRoundMaxBet(0);
            //开启新的一轮
            //清除玩家本轮下注
            room.getBetRoundMap().clear();
            //清空操作过的玩家列表
            room.donePlayerList.clear();
            //已经无法操作的玩家加入doneplayerlist
            for (Player p : room.getIngamePlayers()) {
                if (p != null && p.getBodyChips() <= 0) {
                    room.getDonePlayerList().add(p.getSeatNum());
                }
            }
            //如果公共牌等于五张，切可操作的玩家数小于总玩家数
            if (room.getCommunityCards().size() < 5 && room.getDonePlayerList().size() < room.getIngamePlayers().size()) {
                Player roundTurnNP = getPlayerBySeatNum(room.getRoundturn(), room.getIngamePlayers());
                if (roundTurnNP == null || roundTurnNP.isFold()) {
                    room.setRoundturn(getNextSeatNum(room.getRoundturn(), room));
                }
                room.setNextturn(room.getRoundturn());
                //发送轮到某玩家操作的消息
                msgEventService.sendNextTurnMessage(room.getRoundturn(), room);
                // 轮到下一家操作，并开始计时
                startTimer(room);
                //发公共牌
                int assignCardCount = room.getCommunityCards().size() == 0 ? 3 : 1;
                assignCommonCardByNum(room, assignCardCount);
            } else {
                //结算游戏
                endGame(room);
            }
        }
        return canEndRound;
    }

    @Override
    public Integer getNextSeatNum(Integer seatNum, Room room) {
        Integer begin = seatNum;
        while (true) {
            seatNum = getNextNum(seatNum, room);
            Player pi = getPlayerBySeatNum(seatNum, room.getIngamePlayers());
            if (pi != null && !pi.isFold() && pi.getBodyChips() != 0) {
                break;
            }
            //已经循环一圈
            if (begin == seatNum) {
                break;
            }
        }
        return seatNum;
    }

    @Override
    public Integer getNextNum(Integer seatNum, Room room, Boolean clockwise) {
        Integer begin = seatNum;
        while (true) {
            seatNum = getNextNum(seatNum, room, clockwise);
            Player pi = getPlayerBySeatNum(seatNum, room.getIngamePlayers());
            if (pi != null && !pi.isFold() && pi.getBodyChips() != 0) {
                break;
            }
            //已经循环一圈
            if (begin == seatNum) {
                break;
            }
        }
        return seatNum;
    }

    @Override
    public Integer getNextNum(Integer seatNum, Room room) {
        int nextSeatNum = seatNum + 1;
        if (nextSeatNum >= room.getMaxPlayers()) {
            nextSeatNum = 0;
        }
        return nextSeatNum;
    }

    @Override
    public void updateNextTurn(Room room) {
        Integer thisTurn = room.getNextturn();
        //TODO:特殊判断
        thisTurn = getNextNum(thisTurn, room, true);
        room.setNextturn(thisTurn);
    }

    @Override
    public void updateNextDealer(Room room) {
        Integer d = room.getDealer();
        d = getNextSeatNumDealer(d, room);
        room.setDealer(d);
    }

    @Override
    public Integer getNextSeatNumDealer(Integer seatNum, Room room) {
        Boolean finded = false;
        Integer begin = seatNum;
        while (!finded) {
            seatNum = getNextNum(seatNum, room);
            for (Player pw : room.getWaitPlayers()) {
                if (pw.getSeatNum() == seatNum) {
                    finded = true;
                    break;
                }
            }
            for (Player pi : room.getIngamePlayers()) {
                if (pi.getSeatNum() == seatNum) {
                    finded = true;
                    break;
                }
            }
            //已经循环一遍
            if (begin == seatNum) {
                break;
            }
        }
        return seatNum;
    }

    @Override
    public void assignHandPokerByRoom(Room room) {
        List<Integer>cardList = room.getCardList();
        for (Player p : room.getIngamePlayers()) {
            int[] hankpoker = {cardList.get(0),cardList.get(1)};
            cardList.remove(0);
            cardList.remove(0);
            //玩家手牌
            p.setHandPokers(hankpoker);
        }
    }

    public static boolean removeWaitPlayer(Player player, Room room) {
        boolean success = false;
        Player ret = null;
        if (player != null && room != null) {
            // 等待中的玩家退出房间
            for (int i = 0; i < room.getWaitPlayers().size(); i++) {
                Player p = room.getWaitPlayers().get(i);
                if (p.getId().equals(player.getId())) {
                    ret = room.getWaitPlayers().remove(i);
                }
            }
        }
        if (ret != null) {
            success = true;
        }
        return success;
    }

    public static boolean removeIngamePlayer(Player player, Room room) {
        boolean success = false;
        Player ret = null;
        if (player != null && room != null) {
            // 等待中的玩家退出房间
            for (int i = 0; i < room.getIngamePlayers().size(); i++) {
                Player p = room.getIngamePlayers().get(i);
                if (p.getId().equals(player.getId())) {
                    ret = room.getIngamePlayers().remove(i);
                }
            }
        }
        if (ret != null) {
            success = true;
        }
        return success;
    }


}
